use std::convert::Infallible;
use axum::extract::Query;
use axum::response::{Html, IntoResponse};
use axum::Router;
use axum::routing::get;
use axum::serve::Serve;
use tower_http::trace::TraceLayer;
use serde::Deserialize;
use time::macros::{format_description, offset};
use tower_http::services::{ServeDir, ServeFile};
use tracing_subscriber::fmt::time::OffsetTime;
use tracing_subscriber::fmt::writer::MakeWriterExt;

/**
RUST_LOG=axum=info cargo run
**/


#[tokio::main]
async fn main() {

    // 设置日志时间格式和时区
    let format = format_description!("[year]-[month]-[day] [hour]:[minute]:[second]");
    let log_offset_time = OffsetTime::new(offset!(+08:00), format);

    tracing_subscriber::fmt()
        .with_timer(log_offset_time)
        .init();


    // 需要添加依赖：tower-http = { version = "0.6.2", features = ["trace", "fs"] }
    let serve_dir = ServeDir::new("static")
        .not_found_service(ServeFile::new("static/404.html"));


    let router = Router::new()
        .route("/good", get(handler_good))
        .route("/hello", get(handler_hello))
        .route("/query", get(query))
        .nest_service("/static", serve_dir)
        .layer(TraceLayer::new_for_http());

    let listener = tokio::net::TcpListener::bind("127.0.0.1:3000")
        .await
        .unwrap();

    println!("Listening on http://127.0.0.1:3000");
    axum::serve(listener, router).await.unwrap();
}


// 定义请求参数结构体
#[derive(Debug, Deserialize)]
struct ReqParams {
    name: String,
    age: Option<i32>
}

async fn query(Query(params): Query<ReqParams>) -> impl IntoResponse {
    tracing::info!("run query {:?}", params);
    Html(format!("<h1>Hello, {}!</h1>", params.name))
}

async fn handler_good() -> Html<&'static str> {
    tracing::info!("run good");
    Html("<h1>Good!</h1>")
}
async fn handler_hello() -> Html<&'static str> {
    tracing::info!("run hello");
    Html("<h1>Hello!</h1>")
}